#include "DataIO.h"
#include "../Scene/ZDataManager.h"

GLOBAL_NAMESPACE_BEGIN

#undef TINYXML2_CHECK_VALID_AND_OUTPUT
#define TINYXML2_CHECK_VALID_AND_OUTPUT(ret) if((ret)!=tinyxml2::XML_NO_ERROR) return NULL;


const char* DataIO::Types[] = {
    "image",
    "oneImage",
    "point2d"
};

const char* DataIO::Attributes[] = {
    "id",
    "name",
    "src",
    "type"
};

int DataIO::getType(const char* type)
{
    for (int i = 0; i < sizeof(Types)/sizeof(const char*); i++)
    {
        if (strcmp(type, Types[i])==0)
            return i;
    }
    return -1;
}

bool DataIO::saveDataToXML(const char* xmlFile, DataManager* dataManager)
{
    tinyxml2::XMLDocument doc;
    tinyxml2::XMLElement* imagesElem = parseImagesToXML(&doc, dataManager);
    if (imagesElem)
        doc.LinkEndChild(imagesElem);
    return doc.SaveFile(xmlFile)==tinyxml2::XML_NO_ERROR;
}

tinyxml2::XMLElement* DataIO::parseImagesToXML(tinyxml2::XMLDocument* doc, DataManager* dataManager)
{
    if (!dataManager || dataManager->getImageCount()==0)
        return NULL;

    tinyxml2::XMLElement* elem = doc->NewElement(Types[XML_DATA_IO_Image]);
    for (DataManager::ImageIterator it = dataManager->imageBeginIterator(); it!=dataManager->imageEndIterator(); it++)
    {
        tinyxml2::XMLElement* oneElem = doc->NewElement(Types[XML_DATA_IO_ImageOne]);
        ImageSpace::Image* ima = it->second;
        if (!ima) continue;
        oneElem->SetAttribute(Attributes[XML_DATA_IO_ImageId], ima->getId());
        oneElem->SetAttribute(Attributes[XML_DATA_IO_ImageName], ima->getName().c_str());
        oneElem->SetAttribute(Attributes[XML_DATA_IO_ImageSrc], ima->getFullPath().c_str());
        oneElem->SetAttribute(Attributes[XML_DATA_IO_ImageType], ima->getType());
        elem->LinkEndChild(oneElem);
    }

    return elem;
}

DataManager* DataIO::parseImagesFromXML(tinyxml2::XMLElement* elem, DataManager* dataManager)
{
    if (!dataManager)
        return NULL;

    if (getType(elem->Name())!=XML_DATA_IO_Image)
        return NULL;

    tinyxml2::XMLElement* child = elem->FirstChildElement(Types[XML_DATA_IO_ImageOne]);
    int id = -1;
    std::string name, path;
    int type = -1;
    while (child)
    {
        TINYXML2_CHECK_VALID_AND_OUTPUT(child->QueryIntAttribute(Attributes[XML_DATA_IO_ImageId], &id));
        TINYXML2_CHECK_VALID_AND_OUTPUT(child->QueryIntAttribute(Attributes[XML_DATA_IO_ImageType], &type));
        name = std::string(child->Attribute(Attributes[XML_DATA_IO_ImageName]));
        path = std::string(child->Attribute(Attributes[XML_DATA_IO_ImageSrc]));
        child = child->NextSiblingElement(Types[XML_DATA_IO_ImageOne]);

        ImageSpace::Image *ima = dataManager->readImage(path.c_str(), id);
        if (!ima) continue;
        ima->setName(name);
        ima->setType(ImageSpace::Image::ImageType(type));
    }

    return dataManager;
}

GLOBAL_NAMESPACE_END